﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using Chefbook.HelperMethods;
using Chefbook.UserActions;
using Chefbook.UserActions.ConcreteActions;

namespace Chefbook.ViewModels
{
    public class RecipeEditUndoManager : UserActionManager
    {
        public static readonly DependencyProperty IgnoreTextboxUndoRedoProperty =
            DependencyProperty.RegisterAttached("IgnoreTextboxUndoRedo", typeof(RecipeEditUndoManager), typeof(RecipeEditUndoManager),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnUseGlobalUndoRedoScopeChanged)));

        public static void SetIgnoreTextboxUndoRedo(DependencyObject depObj, bool isSet)
        {
            // never place logic in here, because these methods are not called when things are done in XAML
            depObj.SetValue(IgnoreTextboxUndoRedoProperty, isSet);
        }

        public static RecipeEditUndoManager GetIgnoreTextboxUndoRedo(DependencyObject depObj)
        {
            // never place logic in here, because these methods are not called when things are done in XAML
            return depObj.GetValue(IgnoreTextboxUndoRedoProperty) as RecipeEditUndoManager;
        }

        private static void OnUseGlobalUndoRedoScopeChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
        {
            if (depObj is TextBoxBase)
            {
                if (args.OldValue != null)
                { RemoveTextboxEventHandlers((TextBoxBase)depObj); }
                if (args.NewValue != null)
                { AttachTextboxEventHandlers((TextBoxBase)depObj); }
            }
        }

        private static void AttachTextboxEventHandlers(TextBoxBase textBox)
        {
            textBox.ThrowIfNull("textBox");
            textBox.AddHandler(CommandManager.PreviewExecutedEvent, new ExecutedRoutedEventHandler(RecipeEditUndoManager.IgnoreTextboxUndoRedo), true); // we need to see all events to subvert the built-in undo/redo tracking in the text boxes
        }

        private static void RemoveTextboxEventHandlers(TextBoxBase textBox)
        {
            textBox.ThrowIfNull("textBox");
            textBox.RemoveHandler(CommandManager.PreviewExecutedEvent, new ExecutedRoutedEventHandler(RecipeEditUndoManager.IgnoreTextboxUndoRedo));
        }

        private static void IgnoreTextboxUndoRedo(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.Undo || e.Command == ApplicationCommands.Redo)
            { e.Handled = true; }
        }
    }
}